﻿using System.Net.Http.Headers;
using System.Reflection;
using System.Reflection.Emit;
using rpc_service.cache;

namespace rpc_service.core.support.assembly.il;

public abstract class ILHeader : ILWebRequest
{
    protected void createHeader(ILGenerator il, MethodInfo targetMethod, LocalBuilder requestLocal)
    {
        string[] header = targetMethod.GetCustomAttribute<RPCMethod>()!.Headers;

        if (header == null)
        {
            return;
        }

        for (int i = 0; i < header.Length; i += 2)
        {
            string key = header[i];
            string value = header[i + 1];
            
            if (key == "Authorization" && value == "{token}")
            {
                string methodSignature = targetMethod.GetCustomAttribute<RPCMethod>()!.TokenProvider;
                value = getToken(methodSignature);
            }
            
            il.Emit(OpCodes.Ldloc, requestLocal);
            il.Emit(OpCodes.Callvirt, "HttpRequestMessage".GetTypeByStr().GetProperty("Headers")!.GetGetMethod()!);
            il.Emit(OpCodes.Ldstr, key);
            il.Emit(OpCodes.Ldstr, value);
            il.Emit(OpCodes.Callvirt, "HttpRequestHeaders".GetTypeByStr().GetMethod("Add", new[] { "string".GetTypeByStr(), "string".GetTypeByStr() })!);
        }
    }

    private string getToken(string methodSignature)
    {
        string[] parts = methodSignature.Split('.');
        string methodName = parts[^1];
        string className = string.Join('.', parts.Take(parts.Length - 1));
        Type type = Type.GetType(className)!;
        
        if (type == null)
        {
            throw new Exception("Class not found: " + className);
        }

        MethodInfo method = type.GetMethod(methodName, BindingFlags.Static | BindingFlags.Public)!;
        
        if (method == null)
        {
            throw new Exception("Method not found: " + methodName);
        }

        return (method.Invoke(null, null) as string)!;
    }
}